﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Media;

namespace DARE
{
    /// <summary>
    /// This represents a text field.
    /// </summary>
    [AttrTypeDependentSerializable(typeof(CLineEditData))]
    public class CLineEdit : CWidget
    {
        #region fields
        private bool m_passwordModeEnable = false;
        private string m_line;
        private string m_displayedLine;
        private int m_startDisplayed;
        private int m_lenghtDisplayed;
        private int m_cursorPosition;

        private int m_beginOfSelection;
        private int m_posXBeginOfSelection;
        private Rectangle m_selection;
        private Texture2D m_selectionTexture;

        private Color m_highlightColor;
        private bool m_isSelected;
        private CStaticImage m_cursor;

        private float m_spriteHeight;

        public Vector2 m_scale;
        private Vector2 m_textPos;
        private SpriteFont m_spriteFont;
        private bool m_selectionMode;

        private int m_posClicked;

        #endregion

        #region utils

        private void computeStartDisplayed()
        {
            if (m_cursorPosition > m_line.Length)
                m_cursorPosition = m_line.Length;
            if (m_cursorPosition < m_startDisplayed)
            {
                m_startDisplayed -= m_lenghtDisplayed;
                if (m_startDisplayed < 0)
                    m_startDisplayed = 0;
                computeLenghtDisplayed();
                return;
            }

            if (m_cursorPosition > m_startDisplayed + m_lenghtDisplayed)
            {
                m_startDisplayed += m_cursorPosition - (m_startDisplayed + m_lenghtDisplayed);
                return;
            }

        }

        private void computeLenghtDisplayed()
        {
            //PRobleme, parfois pour la taille il prend le curseur en tant que start. pourtant le start n'est pas sur le curseur.
            bool changed = false;
            for (int i = m_startDisplayed; i < m_line.Length; ++i)
                if (m_spriteFont.MeasureString(m_line.Substring(m_startDisplayed, i - m_startDisplayed)).X > m_rect.Width - 15)
                {
                    m_lenghtDisplayed = (i - 1) - m_startDisplayed;
                    changed = true;
                    break;
                }
            if (m_lenghtDisplayed < 0)
                m_lenghtDisplayed = 0;
            if (!changed && m_lenghtDisplayed < m_line.Length)
                m_lenghtDisplayed = m_line.Length;
        }

        private void computeLenghtDisplayed(int pos)
        {
            for (int i = pos; i < m_line.Length; ++i)
                if (m_spriteFont.MeasureString(m_line.Substring(pos, i - pos)).X > m_rect.Width - 15)
                {
                    m_lenghtDisplayed = (i - 1) - m_startDisplayed;
                    break;
                }
            if (m_lenghtDisplayed < 0)
                m_lenghtDisplayed = 0;
        }

        private void computeLenghtDisplayed(string text)
        {
            m_lenghtDisplayed = -1;
            for (int i = text.Length - 1; i >= 0; --i)
            {
                string tmp = text.Substring(i);
                float widthx = m_spriteFont.MeasureString(tmp).X;
                if (widthx > m_rect.Width - 15)
                {
                    m_lenghtDisplayed = text.Length - i;
                    break;
                }
            }
            if (m_lenghtDisplayed < 0)
                m_lenghtDisplayed = text.Length;
            else if (m_lenghtDisplayed == 0)
                m_lenghtDisplayed = 0;
        }

        #endregion

        #region properties

        public bool PasswordModeEnable { get { return m_passwordModeEnable; } set { m_passwordModeEnable = value; } }

        public string Text { get { return m_line; } }

        public void Add(string text)
        {
            Add(text, 0);
        }
        /// <summary>
        /// Adds text to the given position
        /// </summary>
        public void Add(string text, int pos)
        {
            text = text.Replace("\n", "").Replace("\t", "").Replace("\\", "");
            if (m_line == "")
            {
                m_line = m_line.Insert(pos, text);
                m_cursorPosition = text.Length;
                m_beginOfSelection = m_cursorPosition;
                computeLenghtDisplayed(text);
                computeStartDisplayed();
            }
            else
            {
                if (pos >= m_line.Length)
                    m_line += text;
                else
                    m_line = m_line.Insert(pos, text);
                m_cursorPosition += text.Length;
                computeLenghtDisplayed();
                computeStartDisplayed();
            }
            if (m_lenghtDisplayed + m_startDisplayed >= m_line.Length)
                m_displayedLine = m_line.Substring(m_startDisplayed);
            else
                m_displayedLine = m_line.Substring(m_startDisplayed, m_lenghtDisplayed);
            if (m_passwordModeEnable)
                m_displayedLine = new string('*', m_displayedLine.Length);
        }

        public void Remove(int lenght)
        {
            Remove(lenght, 0);
        }
        /// <summary>
        /// Remove the given length at the given position in the text field.
        /// May be working bad.
        /// </summary>
        public void Remove(int lenght, int pos)
        {
            if (pos == -1)
                pos = m_line.Length - lenght;
            if (m_cursorPosition == 0 && lenght >= 1)
                return;
            m_cursorPosition -= lenght;
            if (m_cursorPosition < 0)
                m_cursorPosition = 0;
            if (lenght > 0)
            {
                if (pos < m_line.Length)
                    m_line = m_line.Remove(pos, lenght);
                else
                    m_line = m_line.Remove(pos, m_line.Length - (pos - lenght));
            }
            if (m_cursorPosition < m_startDisplayed)
                computeLenghtDisplayed(m_cursorPosition);
            else
                computeLenghtDisplayed(m_startDisplayed);
            computeStartDisplayed();
            if (m_startDisplayed + m_lenghtDisplayed < m_line.Length)
                m_displayedLine = m_line.Substring(m_startDisplayed, m_lenghtDisplayed);
            else
                m_displayedLine = m_line.Substring(m_startDisplayed);
        }

        /// <summary>
        /// If the value is between 0 and 1, the position is a percentage of the size of the parent
        /// (if the parent is null, the value is a percentage of the window).
        /// The value is relative to its parent.
        /// </summary>
        public override Vector2 Position
        {
            get
            {
                return base.Position;
            }
            set
            {
                base.Position = value;
                m_scale.Y = ((float)m_rect.Height / m_spriteHeight) / 2.0f;
                m_textPos = new Vector2(m_rect.X, m_rect.Y);
                m_selection.Y = m_rect.Y - 5;
                m_selection.Height = m_rect.Height - 10;
            }
        }

        /// <summary>
        /// If the value is between 0 and 1, the size is a percentage of the size of the parent
        /// (if the parent is null, the value is a percentage of the window).
        /// Else, the value is absolute.
        /// </summary>
        public override Vector2 Size
        {
            get
            {
                return base.Size;
            }
            set
            {
                base.Size = value;
                m_scale.Y = ((float)m_rect.Height / m_spriteHeight) / 2.0f;
                m_textPos = new Vector2(m_rect.X + 5, m_rect.Y);
                m_selection.Y = m_rect.Y - 5;
                m_selection.Height = m_rect.Height - 10;
            }
        }

        /// <summary>
        /// Gets/Sets the rectangle where the widget will be draw.
        /// This value is automatically set when the position and/or the size are set.
        /// If you plan to use a different rectangle than the one automatically created,
        /// we recommand you to use the UseDrawableRect and DrawableRect properties.
        /// </summary>
        /// <seealso cref="UseDrawableRect"/>
        /// <seealso cref="DrawableRect"/>
        public override Rectangle Rect
        {
            get
            {
                return base.Rect;
            }
            set
            {
                base.Rect = value;
                m_scale.Y = ((float)m_rect.Height / m_spriteHeight) / 2.0f;
                m_textPos = new Vector2(m_rect.X + 5, m_rect.Y);
                m_selection.Y = m_rect.Y - 5;
                m_selection.Height = m_rect.Height - 10;
            }
        }

        /// <summary>
        /// Actualizes the widget.
        /// If anything has changed, it will allow this widget to get back its parameters.
        /// For example, if the size of the widget is a percentage of the size of its parent,
        /// if the parent's size changes, it will recalculate the good size of this widget.
        /// (This method is called automatically but you can force a new actualization).
        /// </summary>
        public override void Actualize()
        {
            base.Actualize();
            m_scale.Y = ((float)(m_rect.Height) / m_spriteHeight) / 2.0f;
            m_textPos = new Vector2(m_rect.X + 5, m_rect.Y);
            m_selection.Y = m_rect.Y - 5;
            m_selection.Height = ((m_rect.Height - 10));
        }

        #endregion

        #region ctor

        public CLineEdit(CHUDSystem hud, CWidget parent, string name)
            : base(hud, parent, name)
        {
            CKeyMapper km = CKeyMapper.Instance;
            m_spriteFont = HUD.Skinner.GetSpriteFont("lineeditdefault");
            m_cursorPosition = 0;
            m_startDisplayed = 0;
            m_lenghtDisplayed = 0;
            m_line = "";
            m_texture = HUD.Skinner.GetTexture("lineedit");
            m_cursor = new CStaticImage(hud, this, name + "_cursor");
            m_cursor.Size = new Vector2(3, 20);
            m_cursor.Image = HUD.Skinner.GetTexture("lineeditcarret");
            m_cursor.Hide();
            m_spriteHeight = m_spriteFont.MeasureString("|").Y / 2.0f;
            m_scale = new Vector2(1f, .9f);
            m_selectionMode = false;
            m_posClicked = 0;
            oldCursorPosition = m_cursorPosition;
            m_selection = new Rectangle();
            m_selection.Height = m_rect.Height - 10;
            m_selectionTexture = new Texture2D(Game.GraphicsDevice, 1, 1, false, SurfaceFormat.Color);
            m_highlightColor = new Color(173, 214, 255, 200);
            Color[] c = new Color[1];
            c[0] = m_highlightColor;
            m_selectionTexture.SetData(c);

            Size = new Vector2(200, 20);
        }

        #endregion

        #region event

        private int getCursorPosition(CMouse mouse)
        {
            if (m_displayedLine == null)
                return 0;
            int posX;
            if (mouse.Position.X < m_rect.X)
                return m_startDisplayed - 1;
            posX = (int)(mouse.Position.X - m_rect.X);
            for (int i = 1; i < m_displayedLine.Length; ++i)
            {
                if (m_spriteFont.MeasureString(m_displayedLine.Substring(0, i - 1)).X < posX && m_spriteFont.MeasureString(m_displayedLine.Substring(0, i)).X >= posX)
                {
                    posX = i - 1;
                    break;
                }
            }
            // VOIR POURQUOI QUAND SOURIS A DROITE CA VA A LA FIN DIRECT. (peut etre juste trop rapide et qu'il faut limiter la repetition pour le deplacement a la souris)
            if (posX == (int)(mouse.Position.X - m_rect.X))
                posX = m_startDisplayed + m_lenghtDisplayed + 1;
            return posX + m_startDisplayed;
        }

        private Vector2 getCursorPosition(int relativePos)
        {
            Vector2 absPos = new Vector2();

            absPos.Y = .1f;
            if (m_cursorPosition + 1 > m_line.Length)
                absPos.X = ((float)m_spriteFont.MeasureString(m_line.Substring(m_startDisplayed)).X) / m_rect.Width;
            else
                absPos.X = ((float)m_spriteFont.MeasureString(m_line.Substring(m_startDisplayed, m_cursorPosition - m_startDisplayed + 1)).X) / m_rect.Width;

            return absPos;
        }

        public override bool onClick(CMouse mouse)
        {
            if ((isInArray(oldPressed, Keys.RightShift) || isInArray(oldPressed, Keys.LeftShift)))
            {
                m_posClicked = getCursorPosition(mouse);
                m_selectionMode = true;
                IsLeftClicked = true;

                m_cursorPosition = m_posClicked;
                if (m_cursorPosition > m_line.Length)
                    m_cursorPosition = m_line.Length;
                m_cursor.Position = getCursorPosition(m_posClicked);
                m_cursor.Show();
                highlightSelection();
            }
            else
            {
                m_posClicked = getCursorPosition(mouse);
                m_beginOfSelection = m_posClicked;
                m_posXBeginOfSelection = (int)getCursorPosition(m_posClicked).X;
                m_selectionMode = true;
                IsLeftClicked = true;

                m_cursorPosition = m_posClicked;
                if (m_cursorPosition > m_line.Length)
                    m_cursorPosition = m_line.Length;
                m_cursor.Position = getCursorPosition(m_posClicked);
                m_cursor.Show();
            }

            return true;// base.onClick(mouse);
        }

        public override bool onRelease(CMouse mouse)
        {
            IsLeftClicked = false;
            if (!m_selectionMode)
            {
                m_cursorPosition = m_posClicked;
                if (m_cursorPosition > m_line.Length)
                    m_cursorPosition = m_line.Length;
                m_cursor.Position = getCursorPosition(m_posClicked);
                m_cursor.Show();
            }
            else if (m_beginOfSelection == m_cursorPosition)
                m_selectionMode = false;
            
            m_isSelected = true;
            return true;// base.onRelease(mouse);
        }

        #endregion

        #region actualizeCursorPosition

        private void highlightSelection()//OPTIMISER CETTE METHODE.
        {
            m_posXBeginOfSelection = getRealScreenPos(m_beginOfSelection);
            m_selection.Width = Math.Abs(m_cursor.Rect.X - m_posXBeginOfSelection);
            if (m_cursorPosition < m_beginOfSelection)
                m_selection.X = m_cursor.Rect.X;
            else
                m_selection.X = m_posXBeginOfSelection;
            if (m_selection.X < m_rect.X + 5)
                m_selection.X = m_rect.X + 5;
            if (m_selection.Width > m_rect.Width - 10)
                m_selection.Width = m_rect.Width - 10;
            m_selection.Y = m_cursor.Rect.Y;
            m_selection.Height = m_cursor.Rect.Height;
        }

        int getRealScreenPos(int posInLine)
        {
            int m_cursorRelPos = posInLine - (m_startDisplayed);
            if (m_cursorRelPos <= 0)
                return m_rect.X + 5;
            if (m_cursorRelPos < m_displayedLine.Length)
                return (int)(m_spriteFont.MeasureString(m_displayedLine.Substring(0, m_cursorRelPos)).X + (float)m_rect.X + 5);
            return (int)(m_spriteFont.MeasureString(m_displayedLine).X + (float)m_rect.X + 5);
        }

        void ActualizeCursorPosition(GameTime gameTime)
        {
            Rectangle r = m_cursor.Rect;
            r.X = getRealScreenPos(m_cursorPosition);
            r.Height = m_rect.Height;
            m_cursor.Rect = r;
        }

        #endregion

        #region draw / update
        private int oldCursorPosition = 0;
        private bool isInArray<T, U>(T[] array, U value)
        {
            if (array == null)
                return false;
            foreach (T val in array)
                if (val.ToString() == value.ToString())
                    return true;
            return false;
        }

        Keys[] oldPressed;
        Keys lastPressed = Keys.None;
        double lastPressedTime = 0;
        bool repeat = false;
        string accent = "";
        Dictionary<string, Dictionary<string, string> > voyels = new Dictionary<string, Dictionary<string, string> >
        {
            {"a", new Dictionary<string, string> {{"`", "à"}, {"^", "â"}, {"¨", "ä"}, {"~", "ã"}}},
            {"e", new Dictionary<string, string> {{"`", "è"}, {"^", "ê"}, {"¨", "ë"}}},
            {"i", new Dictionary<string, string> {{"`", "ì"}, {"^", "î"}, {"¨", "ï"}}},
            {"o", new Dictionary<string, string> {{"`", "ò"}, {"^", "ô"}, {"¨", "ö"}, {"~", "õ"}}},
            {"u", new Dictionary<string, string> {{"`", "ù"}, {"^", "û"}, {"¨", "ü"}}},
            {"y", new Dictionary<string, string> {{"¨", "ÿ"}}},
            {"A", new Dictionary<string, string> {{"`", "À"}, {"^", "Â"}, {"¨", "Ä"}, {"~", "Ã"}}},
            {"E", new Dictionary<string, string> {{"`", "È"}, {"^", "Ê"}, {"¨", "Ë"}}},
            {"I", new Dictionary<string, string> {{"`", "Ì"}, {"^", "Î"}, {"¨", "Ï"}}},
            {"O", new Dictionary<string, string> {{"`", "Ò"}, {"^", "Ô"}, {"¨", "Ö"}, {"~", "Õ"}}},
            {"U", new Dictionary<string, string> {{"`", "Ù"}, {"^", "Û"}, {"¨", "Ü"}}},
        };
        private string getAccentChar(string key, string accent)
        {
            if (isInArray<string, string>(voyels.Keys.ToArray(), key) && isInArray<string, string>(voyels[key].Keys.ToArray(), accent))
                return voyels[key][accent];
            return "";
        }

        bool shift = false;
        bool altgr = false;

        //TOUT CE QUI EST LA DESSOUS PEUT ETRE PLUS PROPRISé MAIS TOUT FONCTIONNEEEEEEEEE.
        private void writeText(GameTime gameTime)
        {
            bool changed = false;
            Keys[] pressed = Keyboard.GetState().GetPressedKeys();
            string writed = "";
            bool pass = false;

            shift = (isInArray<Keys, Keys>(pressed, Keys.LeftShift) || isInArray<Keys, Keys>(pressed, Keys.RightShift));
            altgr = (isInArray<Keys, Keys>(pressed, Keys.RightAlt));

            foreach (Keys key in pressed)
            {
                if (key == lastPressed)
                {
                    if (repeat && gameTime.TotalGameTime.TotalMilliseconds > lastPressedTime + 50)
                        pass = true;
                    if (!repeat && gameTime.TotalGameTime.TotalMilliseconds > lastPressedTime + 500)
                    {
                        repeat = true;
                        pass = true;
                    }
                }
                else if (!(key == Keys.LeftShift || key == Keys.RightShift))
                    repeat = false;
                if (!pass && isInArray(oldPressed, key))
                    continue;
                changed = true;
                if (key == Keys.Back)
                {
                    if (m_selectionMode)
                    {
                        m_selectionMode = false;
                        int lenght = Math.Abs(m_cursorPosition - m_beginOfSelection);
                        m_cursorPosition = Math.Min(m_cursorPosition, m_beginOfSelection) + lenght;
                        Remove(lenght, m_cursorPosition - 1);
                    }
                    else
                        Remove(1, m_cursorPosition - 1);
                }
                else if (key == Keys.Delete)
                {
                    if (m_selectionMode)
                    {
                        m_selectionMode = false;
                        int lenght = Math.Abs(m_cursorPosition - m_beginOfSelection);
                        m_cursorPosition = Math.Min(m_cursorPosition, m_beginOfSelection) + lenght;
                        Remove(lenght, m_cursorPosition);
                    }
                    else
                    {
                        if (m_cursorPosition < m_line.Length)
                        {
                            ++m_cursorPosition;
                            Remove(1, m_cursorPosition - 1);
                        }
                    }
                }
                else
                {
                    string tmp = CKeyMapper.Instance.getKeyValue(key, shift, altgr);
                    if (tmp.Length == 1 && m_spriteFont.Characters.Contains(tmp[0]))
                    {
                        if (accent == "" && (tmp == "^" || tmp == "¨" || tmp == "`" || tmp == "~"))
                            accent = tmp;
                        else if (accent != "")
                        {
                            string c;
                            if ((c = getAccentChar(tmp, accent)) != "")
                                writed += c;
                            else
                                writed += accent;
                            accent = "";
                        }
                        else
                            writed += tmp;
                    }
                    else
                    {
                        switch (tmp)
                        {
                            case "END":
                                if (shift && !m_selectionMode)
                                {
                                    m_selectionMode = true;
                                    m_beginOfSelection = m_cursorPosition;
                                    m_posXBeginOfSelection = m_cursor.Rect.X;
                                }
                                m_cursorPosition = m_line.Length;
                                Add("", m_cursorPosition);
                                break;
                            case "HOME":
                                if (shift && !m_selectionMode)
                                {
                                    m_selectionMode = true;
                                    m_beginOfSelection = m_cursorPosition;
                                    m_posXBeginOfSelection = m_cursor.Rect.X;
                                }
                                m_cursorPosition = 0;
                                m_startDisplayed = 0;
                                Remove(0, m_cursorPosition);// Voir ici pour refaire ca plus propre...
                                Remove(0, m_cursorPosition);
                                break;
                            case "LEFT":
                                if (shift && !m_selectionMode)
                                {
                                    m_beginOfSelection = m_cursorPosition;
                                    m_selectionMode = true;
                                    m_posXBeginOfSelection = m_cursor.Rect.X;
                                }
                                --m_cursorPosition;
                                if (m_cursorPosition < 0)
                                    m_cursorPosition = 0;
                                else
                                    Remove(0, m_cursorPosition);
                                break;
                            case "RIGHT":
                                if (shift && !m_selectionMode)
                                {
                                    m_selectionMode = true;
                                    m_beginOfSelection = m_cursorPosition;
                                    m_posXBeginOfSelection = m_cursor.Rect.X;
                                }
                                ++m_cursorPosition;
                                if (m_cursorPosition > m_line.Length)
                                    m_cursorPosition = m_line.Length;
                                else if (m_cursorPosition >= m_startDisplayed + m_lenghtDisplayed)
                                    Add("", m_cursorPosition);
                                break;
                            default:
                                Console.WriteLine(tmp);
                                break;
                        }
                    }
                }
            }
            if (changed)
            {
                if (pressed.Length > 0)
                {
                    lastPressed = pressed[pressed.Length - 1];
                    if (lastPressed == Keys.RightAlt || lastPressed == Keys.RightShift || lastPressed == Keys.LeftShift)
                    {
                        if (pressed.Length > 1)
                            lastPressed = pressed[0];
                        else
                        {
                            repeat = false;
                            lastPressed = Keys.None;
                        }
                    }
                    lastPressedTime = gameTime.TotalGameTime.TotalMilliseconds;
                }
                if (writed != "")
                {
                    if (m_selectionMode)
                    {
                        m_selectionMode = false;
                        int lenght = Math.Abs(m_cursorPosition - m_beginOfSelection);
                        m_cursorPosition = Math.Min(m_cursorPosition, m_beginOfSelection) + lenght;
                        Remove(lenght, m_cursorPosition);
                        Add(writed, m_cursorPosition);
                    }
                    else
                        Add(writed, m_cursorPosition);
                }
                oldPressed = pressed;
            }
            else if (pressed.Length == 0)
            {
                lastPressed = Keys.None;
                oldPressed = pressed;
            }
            else if (shift && pressed.Length == 1)
            {
                lastPressed = Keys.None;
                oldPressed = pressed;
            }
            if (!shift && pressed.Length > 0)
            {
                m_selectionMode = false;
                m_beginOfSelection = m_cursorPosition;
                m_posXBeginOfSelection = m_cursor.Rect.X;
            }
            CDare.Instance.InputMgr.Keyboard.Clear();

        }

        double m_lastRepeated = 0;

        public override bool Update(GameTime gameTime)
        {
            if (m_cursorPosition < 0)
                m_cursorPosition = 0;
            CMouse mouse = CDare.Instance.InputMgr.Mouse;
            if ((mouse.LeftIsPressed || mouse.RightIsPressed ||mouse.MiddleIsPressed) && !isMouseOver(mouse))
            {
                m_isSelected = false;
                m_cursor.Hide();
                m_selectionMode = false;
            }
            if (m_isSelected)
            {
                writeText(gameTime);
                if (gameTime.TotalGameTime.TotalSeconds % 1 < .5)
                    m_cursor.Hide();
                else
                    m_cursor.Show();
            }
            if (IsLeftClicked)
            {
                m_cursorPosition = getCursorPosition(mouse);
                if (m_cursorPosition < m_startDisplayed)
                {
                    --m_cursorPosition;
                    m_selectionMode = true;
                    Remove(0, m_cursorPosition);
                }
                else if (m_cursorPosition > m_startDisplayed + m_lenghtDisplayed)
                {
                    if (gameTime.TotalGameTime.TotalMilliseconds > m_lastRepeated + 200)
                    {
                        m_lastRepeated = gameTime.TotalGameTime.TotalMilliseconds;
                        ++m_cursorPosition;
                        Add("", m_cursorPosition);
                    }
                    m_selectionMode = true;
                }
                if (m_cursorPosition < 0)
                    m_cursorPosition = 0;
            }
            if (oldCursorPosition != m_cursorPosition)
            {
                ActualizeCursorPosition(gameTime);
                if (m_selectionMode)
                    highlightSelection();
                oldCursorPosition = m_cursorPosition;
            }
            return base.Update(gameTime);
        }

        public override bool Draw(GameTime gameTime)
        {
            if (!m_isVisible)
                return false;
            if (this.m_texture != null)
                m_texture.Draw(gameTime);//m_spriteBatch.Draw(this.m_texture, this.m_rect, Color.White);

            if (m_displayedLine != null)
                SpriteBatch.DrawString(m_spriteFont, m_displayedLine, m_textPos, Color, 0.0f, Vector2.Zero, m_scale, SpriteEffects.None, 0);
            foreach (CWidget child in m_children.Values)
                child.Draw(gameTime);
            
            if (m_selectionMode)
                SpriteBatch.Draw(m_selectionTexture, m_selection, m_highlightColor);
            return true;
        }

        #endregion
    }
}
